package space.misiro.ledgers.middleware.api.domain.um

import com.fasterxml.jackson.annotation.JsonProperty
import io.swagger.v3.oas.annotations.media.Schema
import java.util.Date
import java.util.HashMap

/**
 * 数据类表示OAuth 2.0访问令牌及其相关元数据，包含RFC 7519(JWT)标准声明和特定业务扩展字段
 *
 * @property sub 主题标识符（RFC 7519标准声明），通常表示资源所有者的唯一数据库ID
 * @property jti 令牌唯一标识符（RFC 7519标准声明），用于防止重放攻击
 * @property login 资源所有者登录凭证，对应PSD2规范中的pusId标识
 * @property consent PSD2账户信息访问授权详情，包含账户访问范围和有效期等信息
 * @property role 令牌使用时的强制生效角色，用于访问控制决策
 * @property iat 令牌签发时间（RFC 7519标准声明），采用UTC时间格式
 * @property exp 令牌过期时间（RFC 7519标准声明），采用UTC时间格式
 * @property act 令牌持有者声明（RFC 7519标准act声明），存储持有者身份信息的键值对
 * @property scaId 强客户身份验证(Secure Customer Authentication)操作标识，关联登录/支付等敏感操作
 * @property authorisationId 最近一次授权流程标识符，用于跟踪令牌颁发上下文
 * @property tokenUsage 令牌用途分类，如BEARER_TOKEN/REFRESH_TOKEN等类型
 * @property accessToken 实际承载权限的令牌字符串（OAuth 2.0协议规范字段）
 * @property scopes 令牌授权的作用域集合，定义接口访问权限范围
 */
data class AccessTokenTO(
    /**
     * The subject,see rfc7519. This is generally the id of the resource owner.
     */
    @field:Schema(description = "The database id of the initiator of this token")
    var sub: String,

    /**
     * The unique token identifier, see rfc7519
     */
    @field:Schema(description = "The token identifier")
    var jti: String,

    /**
     * The login name of the resource owner (user) on behalf of the holder of this token act.
     * Correspond to the pusId in psd2.
     */
    @field:Schema(description = "The login name of the initiator of this token")
    var login: String,

    /**
     * Consent given by the bearer to the holder of this token.
     */
    @field:Schema(description = "The specification of psd2 account access permission associated with this token")
    var consent: AisConsentTO,

    /**
     * The associated with the token.
     */
    @field:Schema(description = "Role to the inforced when this token is presented.")
    var role: UserRoleTO,

    /**
     * issued at. see rfc7519
     */
    @field:Schema(description = "Issue time")
    var iat: Date,

    /**
     * Expiration. see rfc7519
     */
    @field:Schema(description = "expiration time")
    var exp: Date,

    @field:Schema(description = "The bearer this token.")
    var act: MutableMap<String, String> = HashMap(),

    @field:Schema(description = "The id of the sca object: login, payment, account access")
    @field:JsonProperty("sca_id")
    var scaId: String,

    @field:Schema(description = "The last authorisation id leading to this token")
    @field:JsonProperty("authorisation_id")
    var authorisationId: String,

    @field:Schema(description = "The usage of this token.")
    @field:JsonProperty("token_usage")
    var tokenUsage: TokenUsageTO,

    @field:JsonProperty("access_token")
    var accessToken: String,

    @field:JsonProperty("scopes")
    var scopes: MutableSet<String>,
) {
    /**
     * 验证关联的PSD2授权同意书是否处于有效状态
     *
     * @return 当且仅当consent对象存在且validConsent为true时返回true
     */
    fun hasValidConsent() = consent.validConsent
}
